package com.alpha.bom;

import java.util.Date;
import java.util.TreeMap;

/**
 * This class is the container for the answers of a students
 * to a particular exam. It also maps the students to the exam 
 * and his answers to the correct answer.
 * 
 * @author Ritz Daniel C. Ang
 *
 */
public class ExamResponse {
	private int examResponseId;
	private Exam exam;
	private TreeMap<Question, Answer> answers;
	private boolean complete;
	private Student student;
	private Date dateTaken;

	/**
	 * This is a constructor of the Exam Response Class.
	 * It instantiates the exam and the corresponding student
	 * who took the exam. 
	 * @param exam The exam taken by the student.
	 * @param student The student who took the exam.
	 */
	public ExamResponse(Exam exam, Student student){
		this.setExam(exam);
		this.complete = false;
		answers = new TreeMap<Question, Answer>();
		
		for(Question question : exam.getQuestions()){
			answers.put(question, null);
		}
		this.setComplete(false);
		this.setStudent(student);
	}
	
	/**
	 * Gets the exam response id.
	 * 
	 * @return the examResponseId
	 */
	public int getExamResponseId() {
		return examResponseId;
	}

	/**
	 * Sets the exam response id.
	 *  
	 * @param examResponseId the examResponseId to set
	 */
	public void setExamResponseId(int examResponseId) {
		this.examResponseId = examResponseId;
	}

	/**
	 * Gets the exam taken by the student.
	 * 
	 * @return The exam taken by the student.
	 */
	public Exam getExam() {
		return exam;
	}
	
	/**
	 * Sets the exam taken by the student.
	 * 
	 * @param exam The exam taken by the student.
	 */
	public void setExam(Exam exam) {
		this.exam = exam;
	}
	
	/**
	 * Gets the answers for the exam.
	 * 
	 * @return An array list of answers for the exam.
	 */
	public TreeMap<Question, Answer> getAnswers() {
		return answers;
	}
	
	/**
	 * Sets the answers for the exam.
	 * 
	 * @param answers An array list of answers for the exam.
	 */
	public void setAnswers(TreeMap<Question, Answer> answers) {
		this.answers = answers;
	}
	
	/**
	 * Gets the boolean value which denotes if the 
	 * student has an answer for every question
	 * 
	 * @return The boolean value which denotes if the 
	 * student has an answer for every question or not.
	 */
	public boolean isComplete() {
		return this.complete;
	}
	
	/**
	 * Sets the boolean value which denotes if the 
	 * student has an answer for every question
	 * 
	 * @param complete The boolean value which denotes if the 
	 * student has an answer for every question or not.
	 */
	public void setComplete(boolean complete) {
		this.complete = complete;
	}
	
	/**
	 * Gets the student who took the exam.
	 * 
	 * @return The student who took the exam.
	 */
	public Student getStudent() {
		return student;
	}
	
	/**
	 * Sets the student who took the exam.
	 * 
	 * @param student The student who took the exam.
	 */
	public void setStudent(Student student) {
		this.student = student;
	}

	/**
	 * @return the dateTaken
	 */
	public Date getDateTaken() {
		return dateTaken;
	}

	/**
	 * @param dateTaken the dateTaken to set
	 */
	public void setDateTaken(Date dateTaken) {
		this.dateTaken = dateTaken;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((exam == null) ? 0 : exam.hashCode());
		result = prime * result + ((student == null) ? 0 : student.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ExamResponse other = (ExamResponse) obj;
		if (exam == null) {
			if (other.exam != null)
				return false;
		} else if (!exam.equals(other.exam))
			return false;
		if (student == null) {
			if (other.student != null)
				return false;
		} else if (!student.equals(other.student))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "ExamResponse [exam=" + exam + ", answers=" + answers
				+ ", complete=" + complete + ", student=" + student + "]";
	}

	/**
	 * Adds an answer to the array list of answers.
	 * 
	 * @param answer
	 * @return a boolean value if the the addition of answer
	 * is successful or not.
	 */
	public boolean addAnswer(Question question, Answer answer){
		boolean success = true;
		
		try{
			this.answers.put(question, answer);
		}catch(Exception e){
			success = false;
		}
		
		return success;
	}
	
	/**
	 * Computes the number of correct answers.
	 * 
	 * @return An int value that represents the number
	 * of correct answer.
	 */
	public int computeScore(){
		int score=0;
		for(Question question:answers.keySet()){
			Answer answer = answers.get(question);
			if(answer!=null && question.getCorrectAnswer().equals(answer)){
				score++;
			}
		}
		
		return score;
	}
}
